package com.sprite.utils;

import java.text.DateFormat;
import java.text.ParseException;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author Jackl
 */
public final class UtilMisc {
    private UtilMisc() {
    }

    /**
     * cast to boolean
	 * <p>
	 * UtilMisc.castToBoolean(null)      = false
	 * UtilMisc.castToBoolean(true)        = true
	 * UtilMisc.castToBoolean(false)       = false
	 * UtilMisc.castToBoolean("1")     = true
	 * UtilMisc.castToBoolean("true") = true
	 * UtilMisc.castToBoolean("y") = true
	 * </p>
     * @param obj
     *         one object
     * @return cast result
     */
    public static boolean castToBoolean(Object obj) {
        if (obj instanceof Boolean) {
            return (Boolean) obj;
        }
        if (obj instanceof Number) {
            return Integer.valueOf(0).equals(obj);
        }

        String str = String.valueOf(obj);
        if ("1".equals(str)) {
            return true;
        }
        if ("true".equalsIgnoreCase(str)) {
            return true;
        }

        if ("Y".equalsIgnoreCase(str)) {
            return true;
        }
        return false;
    }

    /**
     * 数组拼接成字符串
     *
     * @param objs
     *         多个值
     * @return 字符
     */
    public static String jointArray(Object... objs) {
        if (objs == null) return null;

        StringBuilder builder = new StringBuilder();
        for (Object obj : objs) {
            builder.append(String.valueOf(obj));
        }
        return builder.toString();
    }

    @SuppressWarnings("unchecked")
    public static <T> T cast(Object object) {
        return (T) object;
    }

    /**
     * 将对象转为int，如果无法转换则返回默认值
     *
     * @param obj
     *         原数据
     * @param defaultValue
     *         默认值
     * @return int
     */
    public static int castToInt(Object obj, int defaultValue) {
        try {
            Integer integer = Integer.valueOf(String.valueOf(obj));
            return integer.intValue();
        } catch (Exception e) {
            return defaultValue;
        }
    }

    public static Date castToDate(Object obj, Date defaultValue) {
        if (obj == null) {
            return defaultValue;
        } else {
            try {
                return DateFormat.getDateInstance(DateFormat.SHORT).parse(obj.toString());
            } catch (ParseException e) {
                e.printStackTrace();
                return defaultValue;
            }
        }
    }

    public static Date castToTime(Object obj, Date defaultValue) {
        if (obj == null) {
            return defaultValue;
        } else {
            try {
                return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM).parse(obj.toString());
            } catch (ParseException e) {
                e.printStackTrace();
                return defaultValue;
            }
        }
    }


    public static <V> List<V> toList(V value) {
        List<V> list = new LinkedList<V>();
        list.add(value);
        return list;
    }

    @SafeVarargs
    public static <V> List<V> toList(V... vs) {
        List<V> list = new LinkedList<V>();
        if (vs != null && vs.length > 0) {
            for (V v : vs) {
                list.add(v);
            }
        }
        return list;
    }

    public static <V, V1 extends V, V2 extends V> List<V> toList(V1 v1, V2 v2) {
        List<V> list = new LinkedList<V>();
        list.add(v1);
        list.add(v2);
        return list;
    }

    public static <V, V1 extends V, V2 extends V, V3 extends V> List<V> toList(V1 v1, V2 v2, V2 v3) {
        List<V> list = new LinkedList<V>();
        list.add(v1);
        list.add(v2);
        list.add(v3);
        return list;
    }

    public static <V, V1 extends V, V2 extends V, V3 extends V, V4 extends V> List<V> toList(V1 v1, V2 v2, V2 v3, V4 v4) {
        List<V> list = new LinkedList<V>();
        list.add(v1);
        list.add(v2);
        list.add(v3);
        list.add(v4);
        return list;
    }

    @SafeVarargs
    public static <T> Set<T> toSet(T... vs) {
        HashSet<T> seTs = new HashSet<>();
        for (T t : vs) {
            seTs.add(t);
        }

        return seTs;
    }

    public static <V, V1 extends V> Map<String, V> toMap(String name1, V1 value1) {
        return populateMap(new HashMap<String, V>(), name1, value1);
    }

    public static <V, V1 extends V, V2 extends V> Map<String, V> toMap(String name1, V1 value1, String name2, V2 value2) {
        return populateMap(new HashMap<String, V>(), name1, value1, name2, value2);
    }

    public static <V, V1 extends V, V2 extends V, V3 extends V> Map<String, V> toMap(String name1, V1 value1, String name2, V2 value2, String name3, V3 value3) {
        return populateMap(new HashMap<String, V>(), name1, value1, name2, value2, name3, value3);
    }

    public static <V, V1 extends V, V2 extends V, V3 extends V> Map<String, V> toMap(String name1, V1 value1, String name2, V2 value2, String name3, V3 value3, Object... params) {
        return populateMap(populateMap(new HashMap<String, V>(), params), name1, value1, name2, value2, name3, value3);
    }

    @SuppressWarnings("unchecked")
    private static <K, V> Map<String, V> populateMap(Map<String, V> map, Object... data) {
        if (data != null && data.length % 2 != 0) {
            throw new IllegalArgumentException("params length must be multiples of 2");
        }
        for (int i = 0; i < data.length; ) {
            map.put((String) data[i++], (V) data[i++]);
        }
        return map;
    }

    public static boolean isEquals(Object obj1, Object obj2) {
        if (obj1 == null || obj2 == null) {
            return false;
        }
        return obj1.equals(obj2);
    }

    public static <T> T ifNullThen(T value, T defaultValue) {
        if (value == null) {
            return defaultValue;
        }

        return value;
    }

    public static String ifEmptyThen(String value, String defaultValue) {
        if (UtilString.isEmpty(value)) {
            return defaultValue;
        }

        return value;
    }
}


